<template>
  <BaseContainer>
    <a-form
      ref="FormRef"
      layout="inline"
      :model="formFields"
      :rules="formRules"
      label-align="left"
      hideRequiredMark
      class="form"
    >
      <a-form-item name="orderId" label="词包id" class="order-id form-item">
        <a-select
          v-model:value="orderId"
          show-search
          class="order-id__search"
          placeholder="请输入词包id"
          allow-clear
          :loading="idLoading"
          :options="orderIds"
          @change="handleOrderIdChange"
        >
          <template v-if="idLoading" #notFoundContent>
            <a-spin size="small" />
          </template>
        </a-select>
      </a-form-item>
      <a-form-item name="keyword" label="关键词" class="order-keyword form-item">
        <a-select
          v-model:value="keyword"
          show-search
          placeholder="请输入要搜索的关键词"
          allow-clear
          class="order-keyword__search"
          :loading="keywordLoading"
          :options="keywords"
          :filter-option="filterOption"
          not-found-content="暂无内容"
          @change="handleKeywordChange"
        />
      </a-form-item>
      <a-form-item label="时间范围" name="startTime" class="form-item">
        <a-button class="mr-2" :danger="timeSelected[Yesterday]" @click="handleDateSelect(Yesterday)">昨日</a-button>
        <a-button class="mr-2" :danger="timeSelected[Week]" @click="handleDateSelect(Week)">近7天</a-button>
        <a-button class="mr-2" :danger="timeSelected[Month]" @click="handleDateSelect(Month)">本月</a-button>
        <a-button class="mr-2" :danger="timeSelected[LastMonth]" @click="handleDateSelect(LastMonth)">上月</a-button>
        <a-range-picker
          class="mr-2"
          v-model:value="dateRange"
          value-format="YYYY-MM-DD HH:mm:ss"
          :disabled-date="disabledDate"
          @change="resetTimeSelected"
        />
        <a-button @click="handleSearch" class="ml-2" type="primary" :loading="loading || lineLoading">搜索</a-button>
      </a-form-item>
    </a-form>
    <Divider class="line" />
    <div class="mb-4">
      <a-radio-group v-model:value="formFields.showType" button-style="solid" @change="loadDashboard" class="mr-3">
        <a-radio-button :value="ShowTypeEnum.Line">展现数据</a-radio-button>
        <a-radio-button :value="ShowTypeEnum.List">上方位排名</a-radio-button>
      </a-radio-group>
      <h3 class="ft-12 font-normal mb-0 mt-5" v-show="formFields.showType === ShowTypeEnum.List">
        此平均排名用于展示您的广告展现在搜索结果上方位（即，第一条自然结果之上）的广告展现平均位次。
      </h3>
    </div>
    <div class="chart" v-if="formFields.showType === ShowTypeEnum.Line">
      <vue-echarts :loading-options="loadingOptions" :loading="lineLoading" :option="option" width="100%" autoresize />
    </div>
    <a-table v-else :data-source="dashboardTable" :pagination="null" :columns="columns" />
  </BaseContainer>
</template>

<script lang="ts" setup>
import { computed, onMounted, reactive, ref } from 'vue'
import VueEcharts from 'vue-echarts'
import { use } from 'echarts/core'
import { LineChart } from 'echarts/charts'
import { SVGRenderer } from 'echarts/renderers'
import { GraphicComponent, GridComponent, TitleComponent } from 'echarts/components'
import getDashboardTable from '@/services/dashboard/getDashboardTable'
import BaseContainer from '@/components/base-container/index.vue'
import Divider from '@/components/divider/index.vue'
import dayjs, { Dayjs } from 'dayjs'
import getOrderKeyword from '@/services/dashboard/getOrderKeyword'
import getOrderId from '@/services/dashboard/getOrderId'
import { isNil } from 'lodash-es'
import { DateRangeEnum, ShowTypeEnum } from '@/views/dashboard/interface'
import is from '@/utils/is'
import { formatDate } from '@/utils'
import { FormInstance, message, TableProps } from 'ant-design-vue'
import getDashboardLine from '@/services/dashboard/getDashboardLine'
import { useMainStore } from '@/store/useMainStore'
import { PlatformEnum } from '@/core/enums/platform'

interface DashboardData {
  orderId?: number
  keyword?: string
  startTime?: Dayjs
  endTime?: Dayjs
  showType: ShowTypeEnum
  clientType?: PlatformEnum
}

const { Yesterday, Week, Month, LastMonth } = DateRangeEnum
const mainStore = useMainStore()

const FormRef = ref<FormInstance>()

const formFields = reactive<DashboardData>({
  orderId: undefined,
  keyword: undefined,
  startTime: undefined,
  endTime: undefined,
  showType: ShowTypeEnum.Line,
  clientType: PlatformEnum.Platform
})

const formRules = reactive({
  orderId: [
    {
      required: true,
      trigger: 'blur',
      message: '请输入词包id'
    }
  ],
  startTime: [
    {
      required: true,
      trigger: 'change',
      message: '请选择时间范围'
    }
  ]
})

const defaultTimeSelected = () => ({
  [Yesterday]: false,
  [Week]: false,
  [Month]: false,
  [LastMonth]: false
})

const timeSelected = reactive<Record<DateRangeEnum, boolean>>(defaultTimeSelected())

const pagination = reactive({
  current: 0,
  pageSize: 99999
})

const columns: TableProps['columns'] = [
  {
    title: '关键词',
    dataIndex: 'keyword',
    key: 'keyword'
  },
  {
    title: '端口',
    dataIndex: 'device',
    key: 'device'
  },
  {
    title: '排名',
    dataIndex: 'avg',
    key: 'avg',
    customRender: ({ text }) => {
      return Number(text).toFixed(1)
    }
  },
  {
    title: '时间',
    dataIndex: 'date',
    key: 'date'
  }
]

const keyword = ref<string | undefined>()

const dateRange = computed({
  get() {
    if (formFields.startTime && formFields.endTime) {
      return [formFields.startTime, formFields.endTime]
    } else {
      return []
    }
  },
  set(val?: Dayjs[]) {
    if (val) {
      formFields.startTime = val[0]
      formFields.endTime = val[1]
    } else {
      formFields.startTime = undefined
      formFields.endTime = undefined
    }
  }
})

const orderId = computed({
  get() {
    return orderIds.value.find((id) => id.label === formFields.orderId)?.value
  },
  set(val?: number) {
    if (is.number(val)) {
      formFields.orderId = orderIds.value.find((id) => id.value === val)?.label
    } else {
      formFields.orderId = undefined
    }
  }
})

const [dashboardTable, fetchDashboardTable, loading] = getDashboardTable()
const [dashboardLine, fetchDashboardLine, lineLoading] = getDashboardLine()
const [keywords, fetchOrderKeyword, keywordLoading] = getOrderKeyword()
const [orderIds, fetchOrderId, idLoading] = getOrderId()
use([LineChart, SVGRenderer, GridComponent, GraphicComponent, TitleComponent])

const loadingOptions = reactive({
  text: '加载中...'
})
const option = computed(() => {
  return {
    title: {
      text: `1.展现是指在用户搜索时，你购买的关键词符合用户的需求，且搜索被触发，该关键词所匹配的创意出现在搜索结果页的次数\n2.仅支持查看昨日之前的数据，数据可能会有波动。`,
      textStyle: {
        fontSize: '12px',
        fontWeight: 'normal',
        lineHeight: 16
      }
    },
    grid: {
      left: '0%',
      right: '0%',
      bottom: '0%',
      containLabel: true
    },
    graphic: {
      type: 'text', // 类型：文本
      left: 'center',
      top: 'middle',
      silent: true, // 不响应事件
      invisible: lineLoading.value || Object.keys(dashboardLine.value).length > 0, // 有数据就隐藏
      style: {
        fill: '#9d9d9d',
        fontWeight: 'bold',
        text: '暂无数据',
        fontFamily: 'Microsoft YaHei',
        fontSize: '25px'
      }
    },
    xAxis: {
      data: Object.keys(dashboardLine.value),
      axisLine: {
        show: true,
        lineStyle: {
          color: '#D1D3D6'
        }
      },
      axisLabel: {
        color: '#777d89'
      },
      axisTick: {
        show: false
      }
    },
    yAxis: {
      axisLabel: {
        show: true,
        color: '#777d89'
      }
    },
    series: [
      {
        type: 'line',
        stack: 'Total',
        label: {
          show: true,
          position: 'top'
        },
        smooth: true,
        data: Object.keys(dashboardLine.value).map((key) => {
          return {
            name: key,
            value: dashboardLine.value[key]
          }
        })
      }
    ]
  }
})

function resetTimeSelected() {
  Object.assign(timeSelected, defaultTimeSelected())
}

function handleDateSelect(target: DateRangeEnum) {
  resetTimeSelected()
  switch (target) {
    case Yesterday: {
      const yesterday = dayjs().subtract(1, 'day')
      dateRange.value = [yesterday.startOf('day'), yesterday.endOf('day')]
      timeSelected.yesterday = true
      break
    }
    case Week: {
      dateRange.value = [dayjs().subtract(1, 'week'), dayjs()]
      timeSelected.week = true
      break
    }
    case Month: {
      dateRange.value = [dayjs().startOf('month'), dayjs().endOf('month')]
      timeSelected.month = true
      break
    }
    default: {
      const month = dayjs().subtract(1, 'month')
      dateRange.value = [month.startOf('month'), month.endOf('month')]
      timeSelected.lastMonth = true
    }
  }
}

function filterOption(input: string, option: any) {
  return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0
}

function handleOrderIdChange(val: string) {
  if (isNil(val)) {
    formFields.clientType = PlatformEnum.Platform
    formFields.keyword = undefined
    keyword.value = undefined
    keywords.value = []
  } else {
    fetchOrderKeyword({
      orderId: formFields.orderId!
    })
    keyword.value = undefined
    formFields.keyword = undefined
  }
}

function disabledDate(current: Dayjs) {
  return current && current < dayjs().subtract(6, 'month')
}

function handleKeywordChange(i: number) {
  formFields.keyword = keywords.value.find((keyword) => keyword.value === i)?.name
  formFields.clientType = keywords.value.find((keyword) => keyword.value === i)?.clientType ?? PlatformEnum.Platform
}

const fetchDashboard = computed(() => {
  if (formFields.showType === ShowTypeEnum.Line) {
    return fetchDashboardLine
  } else {
    return fetchDashboardTable
  }
})

function loadDashboard() {
  FormRef.value?.validate().then(async () => {
    const [err] = await fetchDashboard.value({
      ...formFields,
      keyword: formFields.keyword || '',
      startTime: formatDate(formFields.startTime!, 'YYYY-MM-DD'),
      endTime: formatDate(formFields.endTime!, 'YYYY-MM-DD'),
      startRow: pagination.current,
      rowCount: pagination.pageSize
    })

    if (err) {
      message.error(err.message)
    }
  })
}

function loadOrderId() {
  // 如果是运营，填0
  if (mainStore.isOperation) {
    fetchOrderId({
      customerId: 0,
      sellerId: 0,
      proxyId: 0
    })
  } else {
    fetchOrderId({
      customerId: mainStore.customerId,
      sellerId: mainStore.sellerId,
      proxyId: mainStore.proxyId
    })
  }
}

function handleSearch() {
  FormRef.value?.validate().then(() => {
    loadDashboard()
  })
}

onMounted(() => {
  handleDateSelect(Month)
  loadOrderId()
})
</script>

<script lang="ts">
export default {
  name: 'Dashboard'
}
</script>

<style lang="scss" scoped>
.order-id {
  &__search {
    width: 130px;
  }
}

.order-keyword {
  &__search {
    max-width: 200px;
  }
}

.line {
  margin-top: 0;
}

.chart {
  width: 100%;
  height: 400px;
}

.form-item {
  height: 54px;
  margin-bottom: 0;
}
</style>
